package com.yesep.learn.design.structural.bridge;

import com.yesep.learn.design.common.pojo.*;
import com.yesep.learn.design.common.util.*;

/**
 * 桥接模式（Bridge Pattern）是一种结构型设计模式，其核心思想是将抽象部分与它的实现部分分离，使它们都可以独立地变化。
 * 这种模式通过创建一个桥接结构，将两个独立变化的维度进行解耦，从而提高系统的灵活性和可扩展性。
 * <p>
 * 定义与原理
 * 桥接模式定义了一个用于创建对象的接口，但让子类决定要实例化的类是哪一个。它通过将抽象部分与实现部分分离，使得它们可以独立地变化。
 * 这种分离是通过在抽象类和它的实现类之间引入一个接口（或抽象类）来实现的，这个接口或抽象类作为两者之间的桥梁。
 * <p>
 * 主要角色
 * 桥接模式包含以下主要角色：
 * <p>
 * 抽象化角色（Abstraction）：定义抽象类的接口，并维护一个指向实现化对象（Implementor）类型的对象的引用。
 * 扩展抽象化角色（Refined Abstraction）：是抽象化角色的子类，它实现了在抽象化角色中声明的抽象业务方法，并通过组合关系调用实现化角色的业务方法。
 * 实现化角色（Implementor）：定义实现化角色的接口，这个接口不一定要与抽象化角色的接口完全一致，但它提供的操作接口必须能够完成抽象化角色所声明的抽象业务方法。
 * 具体实现化角色（Concrete Implementor）：是实现化角色的子类，它给出了实现化角色接口的具体实现。
 * 优点
 * 分离抽象部分及具体实现部分：桥接模式使得抽象部分和实现部分可以独立地变化，提高了系统的扩展性。
 * 提高了系统的灵活性：由于抽象与实现之间的解耦，系统可以在不修改现有代码的情况下，增加新的实现或抽象类。
 * 符合开闭原则：通过扩展实现类来适应新情况，而无需修改现有的代码，符合开闭原则（对扩展开放，对修改关闭）。
 * 缺点
 * 增加了系统的理解与设计难度：由于引入了额外的抽象层，系统的设计和理解变得更加复杂。
 * 需要正确地识别系统中两个独立变化的维度：这是使用桥接模式的前提，如果识别不准确，可能会导致设计上的错误。
 * 应用场景
 * 桥接模式适用于以下场景：
 * <p>
 * 一个类存在两个或多个独立变化的维度，且这些维度都需要独立进行扩展。
 * 在抽象和具体实现之间需要增加更多的灵活性。
 * 为了避免使用继承导致的系统类的个数急剧增加。
 * 例如，在支付系统中，支付渠道（如微信支付、支付宝支付）和支付模式（如刷脸支付、指纹支付）是两个独立变化的维度。
 * 使用桥接模式，可以将这两个维度分别设计为独立的继承结构，并通过桥接接口将它们连接起来，从而实现灵活的组合和扩展。
 * <p>
 * 示例
 * 假设有一个支付系统，包含微信支付和支付宝支付两种支付渠道，以及刷脸支付和指纹支付两种支付模式。
 * 可以使用桥接模式来设计这个系统，具体实现可以参照上述的支付系统示例代码。
 */
public class Main {
    public static void main(String[] args) {
        Cat cat = DemoUtil.createCat();
        Bird bird = DemoUtil.createBird();
        Game<RunningAnimal> runGame = new RunGame();
        runGame.setPlayer(cat);
        runGame.run(10);

        Game<FlyingAnimal> flyGame = new FlyGame();
        flyGame.setPlayer(bird);
        flyGame.run(20);
    }
}
